﻿using System;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
using Bling.DSL;
using Bling.WPF;
using Bling.WPF.Util;
using Bling.Core;
using Bling.Util;
using Bling.Physics.UI;
using Bling.Physics;
using Bling.Properties;
using Bling.Mixins;
using Bling.Blocks;
using Bling.Shapes;
using Bling.Angles;

namespace Bling.Tutorial {
  public class PhysicsShape : PhysicsCanvas {
    public class RectBlock : TopBlock<RectBlock, PathShapeBl>, HasShape.IHas<RectBlock>, MouseInput.IHas<RectBlock, PathShapeBl> {
      public RectBlock(BlockManager Manager, CanvasBl Canvas, int Count)
        : base(Manager, Count, (block, idx) => {
          return new PathShapeBl(Canvas) {
            Fill = idx.SelectColor(),
          };
        }) { }
    }

    public class ThumbBlock : TopBlock<ThumbBlock, ThumbBl>, HasPosition.IHas<ThumbBlock> {
      public ThumbBlock(BlockManager Manager, CanvasBl Canvas, int Count)
        : base(Manager, Count, (block, idx) => {
          return new ThumbBl(Canvas) {
            Background = idx.SelectColor(),
            CanDrag = true,
            Size = new Double2Bl(10, 10),
          };
        }) { }
    }
    protected override Action Init(CanvasBl MainCanvas, BlockManager Manager) { // executes before blocks are initialized.
      MainCanvas.Background = Brushes.White;
      var Block = new RectBlock(Manager, MainCanvas, 25);
      var r = new Random();
      Block.ForAll = body => {
        body.Particles().ForAll = particle => {
          particle.Position.Init = Double2Bl.RandomFrom(r) * 500;
        };
      };

      Block.HasShapeE().SetSize(100d);
      Block.HasShapeE().AddRelaxCenter = (target) => {
        Block.ForAll = body => body.Rotation().Relax[.001d] = 0d.PI(); // (2d.PI() / Block.Count) * ((DoubleBl)body.Index);
      };

      var Thumbs = new ThumbBlock(Manager, MainCanvas, Block.Count * HasParticles.Mixin<RectBlock>.ParticleCount);
      Block.AfterMixins = () => {
        Block.ForAll = body => {
          body.Particles().ForAll = particle => {
            var thumb = Thumbs[body.Index * HasParticles.Mixin<RectBlock>.ParticleCount + particle.Index].At;
            particle.Position.Link[!thumb.IsDragging] = thumb.CenterPosition;
            particle.Position.InstallVerletStep(.01);
            particle.Position.Relax[.1] = particle.Position.Clamp(new Double2Bl(0, 0), MainCanvas.Size);
          };
        };
      };
      return () => {
        for (int j = 0; j < Block.Count; j++) {
          Block[j].At.Start = Thumbs[j * HasParticles.Mixin<RectBlock>.ParticleCount + 0].At.CenterPosition;
          for (int i = 0; i < HasParticles.Mixin<RectBlock>.ParticleCount; i++) {
            Block[j].At.Segments.AddOne = new LineSegmentBl() {
              Point = Thumbs[j * HasParticles.Mixin<RectBlock>.ParticleCount + (i + 1) % HasParticles.Mixin<RectBlock>.ParticleCount].At.CenterPosition
            };

          }
        }
        for (int i = 0; i < Thumbs.Count; i++) {
          Thumbs[i].At.Background = (i % HasParticles.Mixin<RectBlock>.ParticleCount).SelectColor();
          Thumbs[i].At.Size = new Double2Bl(10, 10);
        }

      };
    }

  }
}